package by.bucha.testproject.service;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.util.SparseArray;

public class ServiceHelper {

	private ArrayList<ServiceCallbackListener> mCurrentListeners = new ArrayList<ServiceCallbackListener>();

	private AtomicInteger mIdCounter = new AtomicInteger();

	private SparseArray<Intent> mPendingActivities = new SparseArray<Intent>();

	private Application mApplication;

	public ServiceHelper(Application app) {
		this.mApplication = app;
	}

	public void addListener(ServiceCallbackListener currentListener) {
		mCurrentListeners.add(currentListener);
	}

	public void removeListener(ServiceCallbackListener currentListener) {
		mCurrentListeners.remove(currentListener);
	}

	private Intent createIntent(final Context context, String actionLogin,
			final int requestId) {
		Intent i = new Intent(context, ApplicationService.class);
		i.setAction(actionLogin);

		i.putExtra(ApplicationService.EXTRA_STATUS_RECIVER, new ResultReceiver(
				new Handler()) {
			@Override
			protected void onReceiveResult(int resultCode, Bundle resultData) {

				Intent originalIntent = mPendingActivities.get(requestId);
				if (isPending(requestId)) {
					mPendingActivities.remove(requestId);
					for (ServiceCallbackListener currentListener : mCurrentListeners) {
						if (currentListener != null) {
							currentListener.onServiceCallback(requestId,
									originalIntent, resultCode, resultData);
						}
					}
				}
			}
		});

		return i;
	}

	public boolean isPending(int requestId) {
		return mPendingActivities.get(requestId) != null;
	}

	private int createId() {
		return mIdCounter.getAndIncrement();
	}

	private int runRequest(final int requestId, Intent i) {
		mPendingActivities.append(requestId, i);
		mApplication.startService(i);
		return requestId;
	}

	public int insertDatabase(Uri uri, String serializedModel, String modelType) {
		final int requestId = createId();
		Intent i = createIntent(mApplication, ApplicationService.ACTION_INSERT,
				requestId);
		i.putExtra(ApplicationService.EXTRA_MODEL_TYPE, modelType);
		i.putExtra(ApplicationService.EXTRA_URI, uri.toString());
		i.putExtra(ApplicationService.EXTRA_SERIALIZED_MODEL, serializedModel);

		return runRequest(requestId, i);
	}

	public int deleteDatabase(Uri uri, String selection, String[] selectionArgs) {
		final int requestId = createId();
		Intent i = createIntent(mApplication, ApplicationService.ACTION_DELETE,
				requestId);
		i.putExtra(ApplicationService.EXTRA_URI, uri.toString());
		i.putExtra(ApplicationService.EXTRA_SELECTION, selection);
		i.putExtra(ApplicationService.EXTRA_SELECTION_ARGS, selectionArgs);

		return runRequest(requestId, i);
	}

	public int updateDatabase(Uri uri, String selection,
			String[] selectionArgs, String serializedModel, String modelType) {
		final int requestId = createId();
		Intent i = createIntent(mApplication, ApplicationService.ACTION_UPDATE,
				requestId);
		i.putExtra(ApplicationService.EXTRA_URI, uri.toString());
		i.putExtra(ApplicationService.EXTRA_SELECTION, selection);
		i.putExtra(ApplicationService.EXTRA_SELECTION_ARGS, selectionArgs);
		i.putExtra(ApplicationService.EXTRA_SERIALIZED_MODEL, serializedModel);
		i.putExtra(ApplicationService.EXTRA_MODEL_TYPE, modelType);
		return runRequest(requestId, i);
	}

	public int getSingleRow(Uri uri, String selection, String[] selectionArgs,
			String[] columns, String sortOrder) {
		final int requestId = createId();
		Intent i = createIntent(mApplication, ApplicationService.ACTION_QUERY,
				requestId);
		i.putExtra(ApplicationService.EXTRA_URI, uri.toString());
		i.putExtra(ApplicationService.EXTRA_SELECTION, selection);
		i.putExtra(ApplicationService.EXTRA_SELECTION_ARGS, selectionArgs);
		i.putExtra(ApplicationService.EXTRA_COLUMNS, columns);
		i.putExtra(ApplicationService.EXTRA_SORT_ORDER, sortOrder);

		return runRequest(requestId, i);
	}

}
